import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { CreateCommentDto } from './dto/create-comment.dto';
import { Comment } from './entities/comment.entity';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { EntityManager, Repository } from 'typeorm';
import { LikeService } from '../like/like.service';
import { QueryCommentDto } from './dto/query-comment.dto';
import { _BusinessTypeList, filterSensitiveWords } from '../utils';

@Injectable()
export class CommentService {
  @InjectEntityManager()
  private manage: EntityManager;

  @Inject(LikeService)
  private likeService: LikeService;
  // @Inject(BlogService)
  // private blogService: BlogService

  @InjectRepository(Comment)
  private commentRepository: Repository<Comment>;

  // 发评论
  async create(createCommentDto: CreateCommentDto, req: any) {

    const {
      type,
      content,
      avatar,
      commentPic,
      reply,
      parentId,
      createId,
      menberId,
      userId,
      username
    } = createCommentDto;
    const filterWords:string = filterSensitiveWords(content)
    const comment = new Comment();
    comment.ip = req.ip;
    comment.type = type;
    comment.userId = userId ? userId : null; // 游客
    comment.username = username ? username : '游客' + new Date().getTime();
    comment.content = filterWords;
    comment.createId = createId;
    comment.avatar = avatar;
    // 业务关联id
    comment[_BusinessTypeList[type] + 'Id'] = createId;
    if (parentId) {
      comment.parentId = parentId;
    }
    if (reply) {
      comment.reply = 1;
      comment.menberId = menberId;
    }
    if (commentPic) {
      comment.commentPic = commentPic;
    }
    try {
      return await this.manage.save(Comment, comment);
    } catch (error) {
      throw new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  // 移除评论
  async remove(id: number) {
    await this.likeService.removeByCreateId(id);
    return await this.manage.delete(Comment, id);
  }

  // 条件移除
  async removeBy(data: { createId: number; type: number }) {
    await this.manage
      .createQueryBuilder()
      .delete()
      .from(Comment)
      .where('createId = :createId', { createId: data.createId })
      .andWhere('type = :type', { type: data.type })
      .execute();
  }
  // 点赞评论
  async like(createId: number) {
    try {
      await this.commentRepository.increment({ id: createId }, 'like', 1);
    } catch (error) {
      new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  // 取消点赞评论
  async unlike(id: number) {
    try {
      return await this.commentRepository.decrement({ id: id }, 'like', 1);
    } catch (error) {
      new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }

  // 根据id获取评论
  async getCommentsById(params) {
    const { id } = params;
    try {
      const [data, total] = await this.manage
        .createQueryBuilder(Comment, 'c')
        .select('c')
        .where('c.id = :id', { id: id })
        .orWhere('c.parentId = :id', { id: id })
        .orderBy('like', 'ASC')
        .getManyAndCount();
      return {
        data,
        total: total,
      };
    } catch (error) {}
  }

  // 根据业务Id查询评论
  async getByCreateId(queryParam: QueryCommentDto) {
    const { createId, type, userId, orderType } = queryParam;
    let orderBy = {};
    if (orderType === 'new' || !orderType) {
      orderBy = {
        'c.createDate': 'DESC',
      };
    } else {
      orderBy = {
        'c.like': 'DESC',
      };
    }
    try {
      const [commentData, total] = await this.manage
        .createQueryBuilder(Comment, 'c')
        .select('c')
        .where('createId = :createId', { createId })
        .andWhere('type = :type', { type })
        .orderBy(orderBy)
        .getManyAndCount();
      let res;
      // 没有登录的话就不用查用户是否点赞了评论
      if (userId) {
        res = await this.likeService.findByCreateIdAndType({
          type: 3, //评论的业务类型3
          userId,
        });
        // 该用户是否点赞了评论
        commentData.map((i) => {
          if (res?.data.some((commentLike) => commentLike.createId === i.id)) {
            i.action = 1;
          } else {
            i.action = 0;
          }
        });
      }
      if (commentData?.length) {
        const res = commentData
          .filter((i) => !i.parentId)
          .map((item) => {
            const child = commentData.filter((ch) => ch.parentId === item.id);
            return {
              ...item,
              replies: child,
            };
          });
        return {
          data: res,
          total,
        };
      } else {
        return {
          data: [],
          total: 0,
        };
      }
    } catch (error) {
      throw new HttpException(error, HttpStatus.BAD_REQUEST);
    }
  }
}
